package com.yami.shop.api.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.yami.shop.bean.enums.UserFundDetailEnum;
import com.yami.shop.bean.model.User;
import com.yami.shop.bean.model.UserCashOut;
import com.yami.shop.bean.model.UserFundDetail;
import com.yami.shop.bean.param.UserCashOutApprovalParam;
import com.yami.shop.bean.vo.UserCashOutVo;
import com.yami.shop.common.annotation.SysLog;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.payment.WeChatPayment;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.UserCashOutService;
import com.yami.shop.service.UserFundDetailService;
import com.yami.shop.service.UserService;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 会员提现表 前端控制器
 * </p>
 *
 * @author jcd
 * @since 2024-07-26
 */
@RestController
@AllArgsConstructor
@RequestMapping("/p/user/cashOut")
public class UserCashOutController {
    private final UserCashOutService userCashOutService;

    @Autowired
    private UserService userService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private UserFundDetailService userFundDetailService;
    @Autowired
    private WeChatPayment weChatPayment;

    /**
     * 获取配置项
     * @param key
     * @return
     */
    public String  getValueByConfig(String key) {
        List<String> param_value = jdbcTemplate.query("select param_value from tz_sys_config where param_key = ? ", new RowMapper<String>() {
            @Override
            public String mapRow(ResultSet rs, int rowNum) throws SQLException {
                return rs.getString("param_value");
            }
        }, key);

        if(param_value.isEmpty()){
            return null;
        }else{
            return param_value.get(0);
        }
    }

    /**
     * 分页查询
     *
     * @param page        分页对象
     * @param userCashOut 用户地址管理
     * @return 分页数据
     */
    @GetMapping("/page")
    public ServerResponseEntity<IPage<UserCashOut>> page(PageParam page, UserCashOut userCashOut) {
        String userId = SecurityUtils.getUser().getUserId();
        LambdaQueryWrapper<UserCashOut> userCashOutLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userCashOutLambdaQueryWrapper.eq(UserCashOut::getUserAccountTableId,userId);
        userCashOutLambdaQueryWrapper.orderByDesc(UserCashOut::getCreateTime);
        PageParam page1 = userCashOutService.page(page, userCashOutLambdaQueryWrapper);

        List<UserCashOut> records = page1.getRecords();

        List<UserCashOutVo> list1 = new ArrayList<>();
        for (UserCashOut detail : records) {
            UserCashOutVo vo = new UserCashOutVo();
            BeanUtil.copyProperties(detail, vo);

            User byId = userService.getById(detail.getUserAccountTableId());
            if (byId != null) {
                vo.setUserName(byId.getNickName());
            }
            list1.add(vo);
        }

        page1.setRecords(list1);
        return ServerResponseEntity.success(page1);
    }


    /**
     * 通过id查询用户地址管理
     *
     * @param id id
     * @return 单个数据
     */
    @GetMapping("/info/{id}")
    public ServerResponseEntity<UserCashOut> getById(@PathVariable("id") Long id) {
        UserCashOut byId = userCashOutService.getById(id);
        UserCashOutVo vo = new UserCashOutVo();
        BeanUtil.copyProperties(byId, vo);
        User byId1 = userService.getById(byId.getUserAccountTableId());
        if (byId1 != null) {
            vo.setUserName(byId1.getNickName());
        }
        return ServerResponseEntity.success(vo);
    }

    /**
     * 新增用户地址管理
     *
     * @param userCashOut 用户地址管理
     * @return 是否新增成功
     */
    @SysLog("app提交新的提现请求")
    @PostMapping
    @Transactional
    public ServerResponseEntity<Boolean> save(@RequestBody @Valid UserCashOut userCashOut) {
        String userId = SecurityUtils.getUser().getUserId();

        if(!StringUtils.equals(userCashOut.getUserAccountTableId(),userId)){
            return ServerResponseEntity.showFailMsg("不能为其他用户申请提现");
        }

        userCashOut.setCreateTime(new Date());
        //userCashOut.setCreateBy(userId);
        userCashOut.setDelFlag(0);

        if(userCashOut.getState() == 0){
            //新增申请,扣除用户余额

            //个人所得税
            BigDecimal individualIncomeTax = BigDecimal.ZERO;

            if(StringUtils.equals(userCashOut.getUserType(),"leader")){
                if(userCashOut.getCashOutType() == 0){
                    //提现类型 0:团长提现时,满5000需要缴纳个人所得税
                    Map<String,Object> rmap1=userCashOutService.calculateIndividualIncomeTax(userCashOut.getUserAccountTableId(),userCashOut.getCashMoney().toPlainString());
                    BigDecimal individualIncomeTax1 = (BigDecimal)rmap1.get("individualIncomeTax");
                    if(individualIncomeTax1 == null){
                        return ServerResponseEntity.showFailMsg("个人所得税不能为空");
                    }
                    if(userCashOut.getIndividualIncomeTax().compareTo(individualIncomeTax1) != 0){
                        return ServerResponseEntity.showFailMsg("个人所得税不能修改");
                    }

                    individualIncomeTax = individualIncomeTax1;
                }else if(userCashOut.getCashOutType() == 1){
                    //需上传发票
                    //检查是否有发票未审核通过记录
                    Date date = new Date();
                    DateTime begin = DateUtil.beginOfMonth(date);
                    DateTime end = DateUtil.endOfMonth(date);

                    List<UserCashOut> list = userCashOutService.lambdaQuery()
                            .eq(UserCashOut::getUserAccountTable, "tz_user")
                            .eq(UserCashOut::getUserAccountTableField, "distribution_bonus")
                            .eq(UserCashOut::getUserAccountTableId, userCashOut.getUserAccountTableId())
                            .in(UserCashOut::getState, Arrays.asList(3,5))
                            .between(UserCashOut::getCreateTime,begin,end)
                            .list();
                    if(list.size() > 0){
                        return ServerResponseEntity.showFailMsg("本月存在未审核通过发票信息");
                    }
                }
            }

            //拿到提现用户的code对应的openid
            if(StringUtils.equals(userCashOut.getType(),"WeChat")){
                //微信提现
                String payeeInfo = userCashOut.getPayeeInfo();

                Gson gson = new Gson();
                Type mapType = new TypeToken<Map<String, String>>(){}.getType();
                Map<String, String> map = gson.fromJson(payeeInfo, mapType);

                String code = map.get("code");
                if (StringUtils.isBlank(code)){
                    return ServerResponseEntity.showFailMsg("微信提现 code 参数不能为空");
                }

                String openId = weChatPayment.getOpenId(code);
                map.put("openId",openId);

                userCashOut.setPayeeInfo(gson.toJson(map));
            }//...其他暂不验证

            BigDecimal cashMoney = userCashOut.getCashMoney();

            //提现金额加上个人所得税
            cashMoney= cashMoney.add(individualIncomeTax);

            User byId = userService.getById(userCashOut.getUserAccountTableId());
            if(byId == null){
                return ServerResponseEntity.showFailMsg("查询用户 不能为空");
            }

            BigDecimal distributionBonus = byId.getDistributionBonus();
            if(distributionBonus == null){
                return ServerResponseEntity.showFailMsg("查询用户余额为空");
            }

            if(distributionBonus.compareTo(cashMoney) < 0){
                return ServerResponseEntity.showFailMsg("本次提现金额 大于 用户余额");
            }

            //余额减本次提现金额
            BigDecimal subtract = distributionBonus.subtract(cashMoney);

            User user = new User();
            user.setUserId(byId.getUserId());
            user.setDistributionBonus(subtract);
            userService.updateById(user);


            UserFundDetail detail=new UserFundDetail();
            detail.setUserType("tz_user");
            detail.setUid(byId.getUserId());
            detail.setCategory(UserFundDetailEnum.DISTRIBUTION_BONUS.getValue());
            detail.setType(UserFundDetailEnum.TYPE_3.getValue());
            detail.setPm(Integer.valueOf(UserFundDetailEnum.PM_0.getValue()));
            detail.setMoney(cashMoney);
            detail.setResidueMoney(subtract);
            detail.setTitle("提现扣除");
            detail.setDetails("提现扣除:"+cashMoney +", 剩余:"+subtract);
            detail.setDelFlag(0);

            //detail.setCreateBy(userId);
            detail.setCreateTime(new Date());

            //保存流水表关联业务ID
            detail.setOrderNumber(String.valueOf(userCashOut.getId()));

            userFundDetailService.save(detail);
        }

        boolean save = userCashOutService.save(userCashOut);
        return ServerResponseEntity.success(save);
    }

    /**
     * 修改
     * @param userCashOut
     * @return
     */
    @PutMapping
    public ServerResponseEntity<Boolean> updateById(@RequestBody @Valid UserCashOut userCashOut) {
        userCashOut.setUpdateBy(null);
        userCashOut.setUpdateTime(new Date());
        return ServerResponseEntity.success(userCashOutService.updateById(userCashOut));
    }


    /**
     * 查询提现手续费
     *
     * @param cashMoney
     * @return
     */
    @GetMapping("/getServiceCharge")
    public ServerResponseEntity<BigDecimal> getServiceCharge(String cashMoney) {
        String userId = SecurityUtils.getUser().getUserId();

        User byId = userService.getById(userId);
        if(byId == null){
            return ServerResponseEntity.showFailMsg("查询用户 不能为空");
        }

        if (StringUtils.isBlank(cashMoney)) {
            return ServerResponseEntity.showFailMsg("提现金额不能为空");
        }

        if (new BigDecimal(cashMoney).compareTo(BigDecimal.ZERO) <= 0) {
            return ServerResponseEntity.showFailMsg("提现金额不能 小于等于零");
        }

        BigDecimal distributionBonus = byId.getDistributionBonus();
        if(distributionBonus == null){
            return ServerResponseEntity.showFailMsg("查询用户余额为空");
        }

        if(distributionBonus.compareTo(new BigDecimal(cashMoney)) < 0){
            return ServerResponseEntity.showFailMsg("本次提现金额 大于 用户余额");
        }

        String user_cash_out_service_charge = getValueByConfig("user_cash_out_service_charge");
        if(user_cash_out_service_charge == null){
            return ServerResponseEntity.showFailMsg("提现手续费未配置");
        }

        //本次手续费
        BigDecimal multiply = new BigDecimal(cashMoney).multiply(new BigDecimal(user_cash_out_service_charge));

        return ServerResponseEntity.success(multiply);
    }

    /**
     * 计算个人所得税
     * @param uid
     * @param cashOutMoney
     * @return
     */
    @GetMapping("/calculateIndividualIncomeTax")
    public ServerResponseEntity<Map<String,Object>> calculateIndividualIncomeTax(String uid,String cashOutMoney) {
        if(StringUtils.isBlank(uid)){
            return ServerResponseEntity.showFailMsg("uid 不能为空");
        }

        if(StringUtils.isBlank(cashOutMoney)){
            return ServerResponseEntity.showFailMsg("cashOutMoney 不能为空");
        }

        BigDecimal bigDecimal1 = new BigDecimal(cashOutMoney);
        if(bigDecimal1.compareTo(BigDecimal.ZERO) <= 0){
            return ServerResponseEntity.showFailMsg("提现金额不能为 0或负数");
        }

        Map<String,Object> rmap1=userCashOutService.calculateIndividualIncomeTax(uid,cashOutMoney);
        return ServerResponseEntity.success(rmap1);
    }

    /**
     * 获取用户的营业执照使用历史,供本次提现选择使用
     * @param uid
     * @return
     */
    @GetMapping("/getBusinessLicenseByCashOutHistory")
    public ServerResponseEntity<List<Map<String,String>>> getBusinessLicenseByCashOutHistory(String uid) {
        if(StringUtils.isBlank(uid)){
            return ServerResponseEntity.showFailMsg("uid 不能为空");
        }

        List<UserCashOut> list = userCashOutService.lambdaQuery()
                .eq(UserCashOut::getUserAccountTable, "tz_user")
                .eq(UserCashOut::getUserAccountTableField, "distribution_bonus")
                .eq(UserCashOut::getUserAccountTableId, uid)
                .in(UserCashOut::getState, Arrays.asList(1, 3, 4,5))
                .orderByDesc(UserCashOut::getCreateTime)
                .list();
        Gson gson=new Gson();
        List<Map<String,String>> list1=new ArrayList<>();
        for(UserCashOut out:list){
            List<String> businessLicense = list1.stream().map(m -> m.get("businessLicense")).collect(Collectors.toList());
            if(!businessLicense.contains(out.getBusinessLicenseJson())){
                Map map = gson.fromJson(out.getPayeeInfo(), Map.class);

                Map<String,String> map1=new HashMap<>();
                map1.put("name",(String)map.get("name")+"--"+(String)map.get("account"));
                map1.put("businessLicense",out.getBusinessLicenseJson());
                list1.add(map1);
            }
        }
        return ServerResponseEntity.success(list1);
    }
}

